﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Jemgine.MapEditor.Operations
{
    internal class Snapper : Data.Snapper
    {
        EditorState ES = null;
        internal Snapper(EditorState ES)
        {
            this.ES = ES;
        }

        private static Snapper _snapper = null;
        internal static Snapper GetSnapper(EditorState ES)
        {
            if (_snapper == null) _snapper = new Snapper(ES);
            return _snapper;
        }

        #region Snapper Members

        public Vector2 SnapPosition(Vector2 V)
        {
            return Data.SnapHelper.Snap(V, ES._config.GridSpacing);
        }

        public float SnapScale(float s)
        {
            return Data.SnapHelper.Snap(s, ES._config.ScaleSnapIncrement);
        }

        public float SnapRotation(float r)
        {
            return Data.SnapHelper.Snap(r, MathHelper.ToRadians(ES._config.RotationSnapIncrement));
        }

        #endregion
    }

    internal class TransformItem
    {
        internal Object TransformationTag = null;
        internal Object Transformee = null;
    }

	internal class Translate : Operation
	{
        List<TransformItem> Transformees;
        Vector2 MouseDelta;
        bool Snap;

        internal Translate(Data.Translatable Translatable, Vector2 MouseDelta, Object Tag, bool Snap)
        {
            this.Transformees = new List<TransformItem>();
            Transformees.Add(new TransformItem { TransformationTag = Tag, Transformee = Translatable });
            this.MouseDelta = MouseDelta;
            this.Snap = Snap;
        }

        internal Translate(List<TransformItem> Transformees, Vector2 MouseDelta, bool Snap)
        {
            this.Transformees = new List<TransformItem>(Transformees);
            this.MouseDelta = MouseDelta;
            this.Snap = Snap;
        }

		internal override ReturnCode Do(EditorState ES)
		{
            foreach (var Item in Transformees)
            {
                ( Item.Transformee as Data.Translatable ).ApplyTranslation(Item.TransformationTag, MouseDelta);
                if (Snap)
                    ( Item.Transformee as Data.Translatable ).Snap(Snapper.GetSnapper(ES));
            }
			return ReturnCode.AddToUndoStack;
		}

		internal override void Undo(EditorState ES)
		{
            foreach (var Item in Transformees)
                ( Item.Transformee as Data.Translatable ).ApplyTranslation(Item.TransformationTag, Vector2.Zero);
        }
	}
}
